﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using WindowsPhoneHostAgent.UIAutomationServiceReference;
using Microsoft.SmartDevice.Connectivity;
using HostAgentCore;
using System.Net;

namespace WindowsPhoneHostAgent
{
    public class AgentClient : IDisposable
    {
        private readonly ManualResetEvent _stopPlease;
        private Thread _thread;
        string MyIp;

        WindowsPhoneHostAgentController WindowsPhoneHostAgentController;
        public List<DeviceModel> Devices;
        public event EventHandler<SimpleMessageEventArgs> Trace;
        public event EventHandler<TestRunStatusModelArgs> ServerRefresh;

        public AgentClient()
        {
            WindowsPhoneHostAgentController = new WindowsPhoneHostAgentController("Windows Phone Emulator");
            WindowsPhoneHostAgentController.Trace += new EventHandler<SimpleMessageEventArgs>(WindowsPhoneHostAgentController_Trace);
            Devices = new List<DeviceModel>();
            _stopPlease = new ManualResetEvent(false);
        }

        void WindowsPhoneHostAgentController_Trace(object sender, SimpleMessageEventArgs e)
        {
            Trace(this, e);
        }

        public void ConnectToDevices()
        {
            Devices.Clear();
            if (!this.WindowsPhoneHostAgentController.TryConnect()) return;
            SystemInfo systemInfo = WindowsPhoneHostAgentController.Device.GetSystemInfo();

            IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
            MyIp = localIPs.Where(IPAddress => IPAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).FirstOrDefault().ToString(); 


            DeviceModel deviceModel = new DeviceModel()
            {
                Name = WindowsPhoneHostAgentController.Device.Name,
                OS = "Windows Phone",
                OSVersion = systemInfo.OSMajor.ToString(),
                Memery = systemInfo.TotalPhys.ToString(),
                GUID = WindowsPhoneHostAgentController.Device.Id.ToString(),
                IP = MyIp
            };

            Devices.Add(deviceModel);

            using (UIAutomationServiceClient client = new UIAutomationServiceClient())
            {
                client.UpdateDevices(MyIp, Devices.ToArray());
            }
        }

        public void CreateTestRun(int testPlanID)
        {
            using (UIAutomationServiceClient client = new UIAutomationServiceClient())
            {
                string deviceGUID = client.CreateTestRun(testPlanID, Devices[0], "Leo");
                Devices[0].GUID = deviceGUID;
            }
        }

        public void Dispose()
        {
            Stop();
        }

        public void Start()
        {
            _thread = new Thread(Run);
            _thread.Start();       
        }

        public void Stop()
        {
            if (_thread != null)
            {
                _stopPlease.Set();
                _thread.Join();
                _thread = null;
                _stopPlease.Reset();
            }

            WindowsPhoneHostAgentController.ReleaseDeviceConnection();
            using (UIAutomationServiceClient client = new UIAutomationServiceClient())
            {
                Devices.Clear();
                client.UpdateDevices(MyIp, Devices.ToArray());
            }
        }

        private void Run()
        {
            while (_stopPlease.WaitOne(0) == false)
            {
                if (Devices.Count == 0)
                {
                    Thread.Sleep(3000);
                    continue;
                }

                using(UIAutomationServiceClient client = new UIAutomationServiceClient())
                {
                    TestRunStatusModel result = client.GetTestRunStatus(Devices[0].GUID);
                    // to do: check if device is still availbale before executing commands

                    if (result.AgentCommand != "NullCommand")
                    {
                        WindowsPhoneApplicationDefinition appDefinition = new WindowsPhoneApplicationDefinition()
                        {
                            ApplicationId = result.ApplicationDefinition.ApplicationId,
                            ApplicationIconPath = result.ApplicationDefinition.ApplicationIconPath,
                            ApplicationName = result.ApplicationDefinition.ApplicationName,
                            ApplicationPackagePath = result.ApplicationDefinition.ApplicationPackagePath
                        };

                        if (result.AgentCommand.Contains("Stop"))
                        {
                            if (WindowsPhoneHostAgentController.Stop(appDefinition) != StopResult.Success)
                            {
                                throw new Exception("Application not stopped");
                            }
                        }

                        Thread.Sleep(1000);
                        if (result.AgentCommand.Contains("Start"))
                        {
                            if (WindowsPhoneHostAgentController.Start(appDefinition) != StartResult.Success)
                            {
                                throw new Exception("Application not started");
                            }
                        }

                        ServerRefresh(this, new TestRunStatusModelArgs() { TestRunStatusModel = result });
                    }
                }

                Thread.Sleep(3000);
            }
        }
    }
}
